Coverage Summary for Class: PeerServerImpl (org.ethereum.net.server)

Class Class, % Method, % Line, %
PeerServerImpl 0% (0/1) 0% (0/9) 0% (0/40)


1 /* 2  * This file is part of RskJ 3  * Copyright (C) 2017 RSK Labs Ltd. 4  * (derived from ethereumJ library, Copyright (c) 2016 <ether.camp>) 5  * 6  * This program is free software: you can redistribute it and/or modify 7  * it under the terms of the GNU Lesser General Public License as published by 8  * the Free Software Foundation, either version 3 of the License, or 9  * (at your option) any later version. 10  * 11  * This program is distributed in the hope that it will be useful, 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14  * GNU Lesser General Public License for more details. 15  * 16  * You should have received a copy of the GNU Lesser General Public License 17  * along with this program. If not, see <http://www.gnu.org/licenses/>. 18  */ 19  20 package org.ethereum.net.server; 21  22 import io.netty.bootstrap.ServerBootstrap; 23 import io.netty.channel.ChannelFuture; 24 import io.netty.channel.ChannelOption; 25 import io.netty.channel.DefaultMessageSizeEstimator; 26 import io.netty.channel.EventLoopGroup; 27 import io.netty.channel.nio.NioEventLoopGroup; 28 import io.netty.channel.socket.nio.NioServerSocketChannel; 29 import io.netty.handler.logging.LoggingHandler; 30 import org.ethereum.config.SystemProperties; 31 import org.ethereum.listener.EthereumListener; 32 import org.ethereum.net.EthereumChannelInitializerFactory; 33 import org.ethereum.util.ByteUtil; 34 import org.slf4j.Logger; 35 import org.slf4j.LoggerFactory; 36  37 import java.net.InetAddress; 38 import java.util.concurrent.ExecutorService; 39 import java.util.concurrent.Executors; 40  41 /** 42  * This class establishes a listener for incoming connections. 43  * See <a href="http://netty.io">http://netty.io</a>. 44  */ 45 public class PeerServerImpl implements PeerServer { 46  47  private static final Logger logger = LoggerFactory.getLogger("net"); 48  49  private final SystemProperties config; 50  private final EthereumListener ethereumListener; 51  private final EthereumChannelInitializerFactory ethereumChannelInitializerFactory; 52  53  // TODO review this variable use 54  private boolean listening; 55  private ExecutorService peerServiceExecutor; 56  57  public PeerServerImpl(SystemProperties config, EthereumListener ethereumListener, EthereumChannelInitializerFactory ethereumChannelInitializerFactory) { 58  this.config = config; 59  this.ethereumListener = ethereumListener; 60  this.ethereumChannelInitializerFactory = ethereumChannelInitializerFactory; 61  } 62  63  @Override 64  public void start() { 65  if (config.getPeerPort() > 0) { 66  peerServiceExecutor = Executors.newSingleThreadExecutor(runnable -> { 67  Thread thread = new Thread(runnable, "Peer Server"); 68  thread.setUncaughtExceptionHandler( 69  (exceptionThread, exception) -> logger.error("Unable to start peer server", exception) 70  ); 71  return thread; 72  }); 73  peerServiceExecutor.execute(() -> start(config.getBindAddress(), config.getPeerPort())); 74  } 75  76  logger.info("RskJ node started: enode://{}@{}:{}" , ByteUtil.toHexString(config.nodeId()), config.getPublicIp(), config.getPeerPort()); 77  } 78  79  @Override 80  public void stop() { 81  if (peerServiceExecutor != null) { 82  peerServiceExecutor.shutdown(); 83  } 84  } 85  86  private void start(InetAddress host, int port) { 87  // TODO review listening use 88  listening = true; 89  90  EventLoopGroup bossGroup = new NioEventLoopGroup(1); 91  EventLoopGroup workerGroup = new NioEventLoopGroup(); 92  93  EthereumChannelInitializer ethereumChannelInitializer = ethereumChannelInitializerFactory.newInstance(""); 94  95  ethereumListener.trace("Listening on port " + port); 96  97  98  try { 99  ServerBootstrap b = new ServerBootstrap(); 100  101  b.group(bossGroup, workerGroup); 102  b.channel(NioServerSocketChannel.class); 103  104  b.option(ChannelOption.SO_KEEPALIVE, true); 105  b.option(ChannelOption.MESSAGE_SIZE_ESTIMATOR, DefaultMessageSizeEstimator.DEFAULT); 106  b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, config.peerConnectionTimeout()); 107  108  b.handler(new LoggingHandler()); 109  b.childHandler(ethereumChannelInitializer); 110  111  // Start the client. 112  logger.info("Listening for incoming connections, host: {}, port: [{}] ", host, port); 113  logger.info("NodeId: [{}] ", ByteUtil.toHexString(config.nodeId())); 114  115  ChannelFuture f = b.bind(host, port).sync(); 116  117  // Wait until the connection is closed. 118  f.channel().closeFuture().sync(); 119  logger.debug("Connection is closed"); 120  121  // TODO review listening use 122  listening = false; 123  } catch (Exception e) { 124  logger.debug("Exception: {} ({})", e.getMessage(), e.getClass().getName()); 125  throw new Error("Server Disconnected"); 126  } finally { 127  workerGroup.shutdownGracefully(); 128  129  } 130  } 131  132  public boolean isListening() { 133  return listening; 134  } 135 }