Example #1
0
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException {
      String uri = getDecodedUri(request);
      try {
        Pattern p = Pattern.compile(".*/NodePersistentStorage.bin/([^/]+)/([^/]+)");
        Matcher m = p.matcher(uri);
        boolean b = m.matches();
        if (!b) {
          setResponseStatus(response, HttpServletResponse.SC_BAD_REQUEST);
          response.getWriter().write("Improperly formatted URI");
          return;
        }

        String categoryName = m.group(1);
        String keyName = m.group(2);
        NodePersistentStorage nps = H2O.getNPS();
        AtomicLong length = new AtomicLong();
        InputStream is = nps.get(categoryName, keyName, length);
        if (length.get() > (long) Integer.MAX_VALUE) {
          throw new Exception("NPS value size exceeds Integer.MAX_VALUE");
        }
        response.setContentType("application/octet-stream");
        response.setContentLength((int) length.get());
        response.addHeader("Content-Disposition", "attachment; filename=" + keyName + ".flow");
        setResponseStatus(response, HttpServletResponse.SC_OK);
        OutputStream os = response.getOutputStream();
        water.util.FileUtils.copyStream(is, os, 2048);
      } catch (Exception e) {
        sendErrorResponse(response, e, uri);
      } finally {
        logRequest("GET", request, response);
      }
    }
Example #2
0
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException {
      String uri = getDecodedUri(request);
      try {
        Pattern p = Pattern.compile(".*NodePersistentStorage.bin/([^/]+)/([^/]+)");
        Matcher m = p.matcher(uri);
        boolean b = m.matches();
        if (!b) {
          setResponseStatus(response, HttpServletResponse.SC_BAD_REQUEST);
          response.getWriter().write("Improperly formatted URI");
          return;
        }

        String categoryName = m.group(1);
        String keyName = m.group(2);

        InputStream is = extractPartInputStream(request, response);
        if (is == null) {
          return;
        }

        H2O.getNPS().put(categoryName, keyName, is);
        long length = H2O.getNPS().get_length(categoryName, keyName);
        String responsePayload =
            "{ "
                + "\"category\" : "
                + "\""
                + categoryName
                + "\", "
                + "\"name\" : "
                + "\""
                + keyName
                + "\", "
                + "\"total_bytes\" : "
                + length
                + " "
                + "}\n";
        response.setContentType("application/json");
        response.getWriter().write(responsePayload);
      } catch (Exception e) {
        sendErrorResponse(response, e, uri);
      } finally {
        logRequest("POST", request, response);
      }
    }
Example #3
0
 public void handle(
     String target,
     Request baseRequest,
     HttpServletRequest request,
     HttpServletResponse response)
     throws IOException, ServletException {
   H2O.getJetty().handle1(target, baseRequest, request, response);
 }
Example #4
0
  private static void sendErrorResponse(HttpServletResponse response, Exception e, String uri) {
    if (e instanceof H2OFailException) {
      H2OFailException ee = (H2OFailException) e;
      H2OError error = ee.toH2OError(uri);

      Log.fatal("Caught exception (fatal to the cluster): " + error.toString());
      throw (H2O.fail(error.toString()));
    } else if (e instanceof H2OAbstractRuntimeException) {
      H2OAbstractRuntimeException ee = (H2OAbstractRuntimeException) e;
      H2OError error = ee.toH2OError(uri);

      Log.warn("Caught exception: " + error.toString());
      setResponseStatus(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

      // Note: don't use Schema.schema(version, error) because we have to work at bootstrap:
      try {
        @SuppressWarnings("unchecked")
        String s = new H2OErrorV3().fillFromImpl(error).toJsonString();
        response.getWriter().write(s);
      } catch (Exception ignore) {
      }
    } else { // make sure that no Exception is ever thrown out from the request
      H2OError error = new H2OError(e, uri);

      // some special cases for which we return 400 because it's likely a problem with the client
      // request:
      if (e instanceof IllegalArgumentException)
        error._http_status = HttpResponseStatus.BAD_REQUEST.getCode();
      else if (e instanceof FileNotFoundException)
        error._http_status = HttpResponseStatus.BAD_REQUEST.getCode();
      else if (e instanceof MalformedURLException)
        error._http_status = HttpResponseStatus.BAD_REQUEST.getCode();
      setResponseStatus(response, error._http_status);

      Log.warn("Caught exception: " + error.toString());

      // Note: don't use Schema.schema(version, error) because we have to work at bootstrap:
      try {
        @SuppressWarnings("unchecked")
        String s = new H2OErrorV3().fillFromImpl(error).toJsonString();
        response.getWriter().write(s);
      } catch (Exception ignore) {
      }
    }
  }
Example #5
0
    public void doGeneric(String method, HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException {
      try {
        startTransaction(request.getHeader("User-Agent"));

        // Marshal Jetty request parameters to Nano-style.

        // Note that getServletPath does an un-escape so that the %24 of job id's are turned into $
        // characters.
        String uri = request.getServletPath();

        Properties headers = new Properties();
        Enumeration<String> en = request.getHeaderNames();
        while (en.hasMoreElements()) {
          String key = en.nextElement();
          String value = request.getHeader(key);
          headers.put(key, value);
        }

        Properties parms = new Properties();
        Map<String, String[]> parameterMap;
        parameterMap = request.getParameterMap();
        for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
          String key = entry.getKey();
          String[] values = entry.getValue();
          for (String value : values) {
            parms.put(key, value);
          }
        }

        // Make Nano call.
        NanoHTTPD.Response resp = water.api.RequestServer.SERVER.serve(uri, method, headers, parms);

        // Un-marshal Nano response back to Jetty.
        String choppedNanoStatus = resp.status.substring(0, 3);
        assert (choppedNanoStatus.length() == 3);
        int sc = Integer.parseInt(choppedNanoStatus);
        setResponseStatus(response, sc);

        response.setContentType(resp.mimeType);

        Properties header = resp.header;
        Enumeration<Object> en2 = header.keys();
        while (en2.hasMoreElements()) {
          String key = (String) en2.nextElement();
          String value = header.getProperty(key);
          response.setHeader(key, value);
        }

        OutputStream os = response.getOutputStream();
        if (resp instanceof NanoHTTPD.StreamResponse) {
          NanoHTTPD.StreamResponse ssr = (NanoHTTPD.StreamResponse) resp;
          ssr.streamWriter.writeTo(os);
        } else {
          InputStream is = resp.data;
          FileUtils.copyStream(is, os, 1024);
        }
      } finally {
        logRequest(method, request, response);
        // Handle shutdown if it was requested.
        if (H2O.getShutdownRequested()) {
          (new Thread() {
                public void run() {
                  boolean[] confirmations = new boolean[H2O.CLOUD.size()];
                  if (H2O.SELF.index() >= 0) {
                    confirmations[H2O.SELF.index()] = true;
                  }
                  for (H2ONode n : H2O.CLOUD._memary) {
                    if (n != H2O.SELF)
                      new RPC(n, new ShutdownTsk(H2O.SELF, n.index(), 1000, confirmations)).call();
                  }
                  try {
                    Thread.sleep(2000);
                  } catch (Exception ignore) {
                  }
                  int failedToShutdown = 0;
                  // shutdown failed
                  for (boolean b : confirmations) if (!b) failedToShutdown++;
                  Log.info(
                      "Orderly shutdown: "
                          + (failedToShutdown > 0
                              ? failedToShutdown + " nodes failed to shut down! "
                              : "")
                          + " Shutting down now.");
                  H2O.closeAll();
                  H2O.exit(failedToShutdown);
                }
              })
              .start();
        }
        endTransaction();
      }
    }
Example #6
0
  protected void createServer(Connector connector) throws Exception {
    _server.setConnectors(new Connector[] {connector});

    if (H2O.ARGS.hash_login || H2O.ARGS.ldap_login) {
      // REFER TO
      // http://www.eclipse.org/jetty/documentation/9.1.4.v20140401/embedded-examples.html#embedded-secured-hello-handler
      if (H2O.ARGS.login_conf == null) {
        Log.err("Must specify -login_conf argument");
        H2O.exit(1);
      }

      LoginService loginService;
      if (H2O.ARGS.hash_login) {
        Log.info("Configuring HashLoginService");
        loginService = new HashLoginService("H2O", H2O.ARGS.login_conf);
      } else if (H2O.ARGS.ldap_login) {
        Log.info("Configuring JAASLoginService (with LDAP)");
        System.setProperty("java.security.auth.login.config", H2O.ARGS.login_conf);
        loginService = new JAASLoginService("ldaploginmodule");
      } else {
        throw H2O.fail();
      }
      IdentityService identityService = new DefaultIdentityService();
      loginService.setIdentityService(identityService);
      _server.addBean(loginService);

      // Set a security handler as the first handler in the chain.
      ConstraintSecurityHandler security = new ConstraintSecurityHandler();

      // Set up a constraint to authenticate all calls, and allow certain roles in.
      Constraint constraint = new Constraint();
      constraint.setName("auth");
      constraint.setAuthenticate(true);

      // Configure role stuff (to be disregarded).  We are ignoring roles, and only going off the
      // user name.
      //
      //   Jetty 8 and prior.
      //
      //     Jetty 8 requires the security.setStrict(false) and ANY_ROLE.
      security.setStrict(false);
      constraint.setRoles(new String[] {Constraint.ANY_ROLE});

      //   Jetty 9 and later.
      //
      //     Jetty 9 and later uses a different servlet spec, and ANY_AUTH gives the same behavior
      //     for that API version as ANY_ROLE did previously.  This required some low-level
      // debugging
      //     to figure out, so I'm documenting it here.
      //     Jetty 9 did not require security.setStrict(false).
      //
      // constraint.setRoles(new String[]{Constraint.ANY_AUTH});

      ConstraintMapping mapping = new ConstraintMapping();
      mapping.setPathSpec("/*"); // Lock down all API calls
      mapping.setConstraint(constraint);
      security.setConstraintMappings(Collections.singletonList(mapping));

      // Authentication / Authorization
      security.setAuthenticator(new BasicAuthenticator());
      security.setLoginService(loginService);

      // Pass-through to H2O if authenticated.
      registerHandlers(security);
      _server.setHandler(security);
    } else {
      registerHandlers(_server);
    }

    _server.start();
  }