Search in sources :

Example 1 with JettyHTTPD

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);
}
Also used : JettyHTTPD(water.JettyHTTPD)

Aggregations

JettyHTTPD (water.JettyHTTPD)1