@Override
 protected void processMethod(StageMethod method) {
   switch (method.getStageMethod()) {
     case STAGEOP_PARSE_AND_EXECUTE:
       parseAndExecute(method);
       break;
     default:
       method.getRq().setError(ErrorType.INTERNAL_SERVER_ERROR, "unknown stage operation");
       master.requestFinished(method.getRq());
   }
 }
Example #2
0
  /**
   * Parse request and execute method
   *
   * @param method stagemethod to execute
   */
  private void parseAndExecute(StageMethod method) {

    final MRCRequest rq = method.getRq();
    final RPCServerRequest rpcRequest = rq.getRPCRequest();
    final RPCHeader header = rpcRequest.getHeader();
    final RPCHeader.RequestHeader rqHeader = header.getRequestHeader();

    if (header.getMessageType() != MessageType.RPC_REQUEST) {
      rq.setError(
          ErrorType.GARBAGE_ARGS,
          POSIXErrno.POSIX_ERROR_EIO,
          "expected RPC request message type but got " + header.getMessageType());
      return;
    }

    final MRCOperation op = operations.get(rqHeader.getProcId());

    if (op == null) {
      rq.setError(
          ErrorType.INVALID_PROC_ID,
          "requested operation (" + rqHeader.getProcId() + ") is not available on this MRC");
      master.requestFinished(rq);
      return;
    }

    if (Logging.isDebug())
      Logging.logMessage(
          Logging.LEVEL_DEBUG,
          Category.stage,
          this,
          "operation for request %s: %s",
          rq.toString(),
          op.getClass().getSimpleName());

    if (statisticsEnabled) {
      _opCountMap.put(rqHeader.getProcId(), _opCountMap.get(rqHeader.getProcId()) + 1);
    }

    // parse request arguments
    ErrorRecord error = op.parseRequestArgs(rq);
    if (error != null) {
      rq.setError(error);
      master.requestFinished(rq);
      return;
    }

    try {

      // get the auth data if available
      Auth auth =
          header.getRequestHeader().hasAuthData() ? header.getRequestHeader().getAuthData() : null;

      // get the user credentials
      org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials ctx =
          op.getUserCredentials(rq);

      if (ctx != null)
        try {
          UserCredentials cred =
              master
                  .getAuthProvider()
                  .getEffectiveCredentials(ctx, rpcRequest.getConnection().getChannel());
          rq.getDetails().superUser = cred.isSuperUser();
          rq.getDetails().groupIds = cred.getGroupIDs();
          rq.getDetails().userId = cred.getUserID();
          rq.getDetails().auth = auth;
          rq.getDetails().password =
              auth != null && auth.hasAuthPasswd() ? auth.getAuthPasswd().getPassword() : "";
        } catch (AuthenticationException ex) {
          throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, ex.getMessage());
        }

    } catch (Exception exc) {

      method
          .getRq()
          .setError(
              ErrorType.INTERNAL_SERVER_ERROR, "could not initialize authentication module", exc);
      master.requestFinished(method.getRq());
      return;
    }

    execute(op, method);
  }
  /**
   * Parse request and execute method
   *
   * @param method stagemethod to execute
   */
  private void parseAndExecute(StageMethod method) {

    final MRCRequest rq = method.getRq();
    final RPCServerRequest rpcRequest = rq.getRPCRequest();
    final RPCHeader header = rpcRequest.getHeader();
    final RPCHeader.RequestHeader rqHeader = header.getRequestHeader();

    if (header.getMessageType() != MessageType.RPC_REQUEST) {
      rq.setError(
          ErrorType.GARBAGE_ARGS,
          POSIXErrno.POSIX_ERROR_EIO,
          "expected RPC request message type but got " + header.getMessageType());
      return;
    }

    final MRCOperation op = operations.get(rqHeader.getProcId());

    if (op == null) {
      rq.setError(
          ErrorType.INVALID_PROC_ID,
          "requested operation (" + rqHeader.getProcId() + ") is not available on this MRC");
      master.requestFinished(rq);
      return;
    }

    if (Logging.isDebug())
      Logging.logMessage(
          Logging.LEVEL_DEBUG,
          Category.stage,
          this,
          "operation for request %s: %s",
          rq.toString(),
          op.getClass().getSimpleName());

    if (statisticsEnabled) {
      _opCountMap.put(rqHeader.getProcId(), _opCountMap.get(rqHeader.getProcId()) + 1);
    }

    // parse request arguments
    ErrorRecord error = op.parseRequestArgs(rq);
    if (error != null) {
      rq.setError(error);
      master.requestFinished(rq);
      return;
    }

    try {

      // get the auth data if available
      Auth auth =
          header.getRequestHeader().hasAuthData() ? header.getRequestHeader().getAuthData() : null;

      // get the user credentials
      org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials ctx =
          op.getUserCredentials(rq);

      if (ctx != null)
        try {
          UserCredentials cred =
              master
                  .getAuthProvider()
                  .getEffectiveCredentials(ctx, rpcRequest.getConnection().getChannel());
          rq.getDetails().superUser = cred.isSuperUser();
          rq.getDetails().groupIds = cred.getGroupIDs();
          rq.getDetails().userId = cred.getUserID();
          rq.getDetails().auth = auth;
          rq.getDetails().password =
              auth != null && auth.hasAuthPasswd() ? auth.getAuthPasswd().getPassword() : "";
        } catch (AuthenticationException ex) {
          throw new UserException(POSIXErrno.POSIX_ERROR_EPERM, ex.getMessage());
        }

    } catch (Exception exc) {

      method
          .getRq()
          .setError(
              ErrorType.INTERNAL_SERVER_ERROR, "could not initialize authentication module", exc);
      master.requestFinished(method.getRq());
      return;
    }

    try {

      if (Logging.isDebug()) {

        StringBuffer params = new StringBuffer();
        Map<FieldDescriptor, Object> fieldMap =
            rq.getRequestArgs() == null ? null : rq.getRequestArgs().getAllFields();
        if (fieldMap != null) {
          int i = 0;
          for (Entry<FieldDescriptor, Object> entry : fieldMap.entrySet()) {
            params.append(
                entry.getKey().getName()
                    + "='"
                    + entry.getValue()
                    + (i == fieldMap.size() - 1 ? "'" : "', "));
            i++;
          }
        }
        Logging.logMessage(
            Logging.LEVEL_DEBUG,
            this,
            "parsed request: %s (%s)\n",
            StatusPage.getOpName(rqHeader.getProcId()),
            params.toString());
      }

      op.startRequest(rq);

    } catch (UserException exc) {
      reportUserError(op, rq, exc, exc.getErrno());

    } catch (MRCException exc) {
      Throwable cause = exc.getCause();
      if (cause instanceof DatabaseException
          && ((DatabaseException) cause).getType() == ExceptionType.NOT_ALLOWED)
        reportUserError(op, rq, exc, POSIXErrno.POSIX_ERROR_EPERM);
      else reportServerError(op, rq, exc);

    } catch (DatabaseException exc) {
      if (exc.getType() == ExceptionType.NOT_ALLOWED) {
        reportUserError(op, rq, exc, POSIXErrno.POSIX_ERROR_EPERM);
      } else if (exc.getType() == ExceptionType.REDIRECT) {
        try {
          redirect(
              rq,
              exc.getAttachment() != null
                  ? (String) exc.getAttachment()
                  : master.getReplMasterUUID());
        } catch (MRCException e) {
          reportServerError(op, rq, e);
        }
      } else reportServerError(op, rq, exc);

    } catch (Throwable exc) {
      reportServerError(op, rq, exc);
    }
  }