Java tutorial
/* * Copyright (c) 2016 Catavolt Inc. All rights reserved. * * This file is part of Ozy. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package ozy.server; 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; import ozy.klvm.Root; import java.io.File; import java.util.Arrays; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; /** * This class was adapted from the Netty example at: * http://netty.io/4.0/xref/io/netty/example/http/snoop/HttpSnoopServer.html */ public class Server { private static Server _current; private static EventLoopGroup _bossGroup = new NioEventLoopGroup(1); private static EventLoopGroup _workerGroup = new NioEventLoopGroup(); private Channel _channel; private final int _port; private final Router _router; //-------------------------------------------------------------------------- // CLASS METHODS //-------------------------------------------------------------------------- public static void create(String[] args) throws Exception { List<String> argsList = Arrays.asList(args); String rootDirPath = getArgAtOption(argsList, "-home"); String secret = getArgAtOption(argsList, "-secret"); if (secret.length() != 32) { throw new IllegalArgumentException("Secret argument must be 32 characters in length"); } File rootDir = new File(rootDirPath); String instanceId = Root.createInstance(rootDir, secret); System.out.println("Root instance created: " + instanceId); } public static Server current() { return _current; } public static void shutdown() { current().channel().close(); _bossGroup.shutdownGracefully(); _workerGroup.shutdownGracefully(); } public static void start(String[] args) throws Exception { System.out.println("[Server] starting"); Logger.getLogger("io.netty").setLevel(Level.FINEST); List<String> argsList = Arrays.asList(args); String homeDir = getArgAtOption(argsList, "-home"); String rootDir = getArgAtOption(argsList, "-root"); String portString = getArgAtOption(argsList, "-port"); Root.setInstance(homeDir, rootDir); int port = Integer.parseInt(portString); _current = new Server(port, new Router()); _current.run(); } // ~~~~~~~~~~~~~~~~~~~~~~~~~ PRIVATE ~~~~~~~~~~~~~~~~~~~~~~~~~ // private static String getArgAtOption(List<String> argsList, String option) throws Exception { int optionIndex = argsList.indexOf(option); if (optionIndex < 0) { throw new IllegalArgumentException(String.format("Option %s is required", option)); } if (!(optionIndex < argsList.size() - 1)) { throw new IllegalArgumentException(String.format("A value must follow the %s option", option)); } return argsList.get(optionIndex + 1); } //-------------------------------------------------------------------------- // CONSTRUCTORS //-------------------------------------------------------------------------- // ~~~~~~~~~~~~~~~~~~~~~~~~~ PRIVATE ~~~~~~~~~~~~~~~~~~~~~~~~~ // private Server(int port, Router router) { _port = port; _router = router; } //-------------------------------------------------------------------------- // INSTANCE METHODS //-------------------------------------------------------------------------- // ~~~~~~~~~~~~~~~~~~~~~~~~~ PACKAGE PRIVATE ~~~~~~~~~~~~~~~~~~~~~~~~~ // final Channel channel() { return _channel; } final int port() { return _port; } final Router router() { return _router; } final void run() throws Exception { System.out.println("[Server] bootstrapping"); ServerBootstrap b = new ServerBootstrap(); b.group(_bossGroup, _workerGroup).channel(NioServerSocketChannel.class) .handler(new LoggingHandler(LogLevel.INFO)).childHandler(new ServerInitializer(this)); System.out.println("[Server] binding to port: " + port()); _channel = b.bind(port()).sync().channel(); System.out.println("[Server] running"); _channel.closeFuture().sync(); System.out.println("[Server] ended"); } }