use of water.JettyHTTPD in project h2o-3 by h2oai.
the class NetworkInit method initializeNetworkSockets.
// Parse arguments and set cloud name in any case. Strip out "-name NAME"
// and "-flatfile <filename>". Ignore the rest. Set multi-cast port as a hash
// function of the name. Parse node ip addresses from the filename.
public static void initializeNetworkSockets() {
// Assign initial ports
H2O.API_PORT = H2O.ARGS.port == 0 ? H2O.ARGS.baseport : H2O.ARGS.port;
// Late instantiation of Jetty object, if needed.
if (H2O.getJetty() == null && !H2O.ARGS.disable_web) {
H2O.setJetty(new JettyHTTPD());
}
// API socket is only used to find opened port on given ip.
ServerSocket apiSocket = null;
//
while (true) {
H2O.H2O_PORT = H2O.API_PORT + 1;
try {
// cnc: this is busted on windows. Back to the old code.
if (!H2O.ARGS.disable_web) {
apiSocket = // Listen to any interface
H2O.ARGS.web_ip == null ? new ServerSocket(H2O.API_PORT) : new ServerSocket(H2O.API_PORT, -1, getInetAddress(H2O.ARGS.web_ip, null));
apiSocket.setReuseAddress(true);
}
// Bind to the UDP socket
_udpSocket = DatagramChannel.open();
_udpSocket.socket().setReuseAddress(true);
InetSocketAddress isa = new InetSocketAddress(H2O.SELF_ADDRESS, H2O.H2O_PORT);
_udpSocket.socket().bind(isa);
// Bind to the TCP socket also
_tcpSocket = ServerSocketChannel.open();
_tcpSocket.socket().setReceiveBufferSize(water.AutoBuffer.TCP_BUF_SIZ);
_tcpSocket.socket().bind(isa);
// Warning: There is a ip:port race between socket close and starting Jetty
if (!H2O.ARGS.disable_web) {
apiSocket.close();
H2O.getJetty().start(H2O.ARGS.web_ip, H2O.API_PORT);
}
break;
} catch (Exception e) {
Log.trace("Cannot allocate API port " + H2O.API_PORT + " because of following exception: ", e);
if (apiSocket != null)
try {
apiSocket.close();
} catch (IOException ohwell) {
Log.err(ohwell);
}
if (_udpSocket != null)
try {
_udpSocket.close();
} catch (IOException ie) {
}
if (_tcpSocket != null)
try {
_tcpSocket.close();
} catch (IOException ie) {
}
apiSocket = null;
_udpSocket = null;
_tcpSocket = null;
if (H2O.ARGS.port != 0)
H2O.die("On " + H2O.SELF_ADDRESS + " some of the required ports " + H2O.ARGS.port + ", " + (H2O.ARGS.port + 1) + " are not available, change -port PORT and try again.");
}
// Try next available port to bound
H2O.API_PORT += 2;
if (H2O.API_PORT > (1 << 16)) {
Log.err("Cannot find free port for " + H2O.SELF_ADDRESS + " from baseport = " + H2O.ARGS.baseport);
H2O.exit(-1);
}
}
// Is IPv6 address was assigned to this node
boolean isIPv6 = H2O.SELF_ADDRESS instanceof Inet6Address;
H2O.SELF = H2ONode.self(H2O.SELF_ADDRESS);
if (!H2O.ARGS.disable_web) {
Log.info("Internal communication uses port: ", H2O.H2O_PORT, "\n" + "Listening for HTTP and REST traffic on " + H2O.getURL(H2O.getJetty().getScheme()) + "/");
}
try {
Log.debug("Interface MTU: ", (NetworkInterface.getByInetAddress(H2O.SELF_ADDRESS)).getMTU());
} catch (SocketException se) {
Log.debug("No MTU due to SocketException. " + se.toString());
}
String embeddedConfigFlatfile = null;
AbstractEmbeddedH2OConfig ec = H2O.getEmbeddedH2OConfig();
if (ec != null) {
// TODO: replace this call with ec.notifyAboutH2oCommunicationChannel(H2O.SELF_ADDRESS, H2O.H2O_PORT)
// As of right now, the function notifies about the H2O.API_PORT, and then the listener adds +1
// to that in order to determine the H2O_PORT (which what it really cares about). Such
// assumption is dangerous: we should be free of using independent API_PORT and H2O_PORT,
// including the ability of not using any API_PORT at all...
ec.notifyAboutEmbeddedWebServerIpPort(H2O.SELF_ADDRESS, H2O.API_PORT);
if (ec.providesFlatfile()) {
try {
embeddedConfigFlatfile = ec.fetchFlatfile();
} catch (Exception e) {
Log.err("Failed to get embedded config flatfile");
Log.err(e);
H2O.exit(1);
}
}
}
// Read a flatfile of allowed nodes
if (embeddedConfigFlatfile != null)
H2O.setFlatfile(parseFlatFileFromString(embeddedConfigFlatfile));
else
H2O.setFlatfile(parseFlatFile(H2O.ARGS.flatfile));
// All the machines has to agree on the same multicast address (i.e., multicast group)
// Hence use the cloud name to generate multicast address
// Note: if necessary we should permit configuration of multicast address manually
// Note:
// - IPv4 Multicast IPs are in the range E1.00.00.00 to EF.FF.FF.FF
// - IPv6 Multicast IPs are in the range defined in NetworkUtils
int hash = H2O.ARGS.name.hashCode();
try {
H2O.CLOUD_MULTICAST_GROUP = isIPv6 ? NetworkUtils.getIPv6MulticastGroup(hash, NetworkUtils.getIPv6Scope(H2O.SELF_ADDRESS)) : NetworkUtils.getIPv4MulticastGroup(hash);
} catch (UnknownHostException e) {
Log.err("Cannot get multicast group address for " + H2O.SELF_ADDRESS);
Log.throwErr(e);
}
H2O.CLOUD_MULTICAST_PORT = NetworkUtils.getMulticastPort(hash);
}
Aggregations