@Override
  public void handleRequest(final HttpServerExchange exchange) throws Exception {
    final FormDataParser parser = formParserFactory.createParser(exchange);
    if (parser == null) {
      Common.UNSUPPORTED_MEDIA_TYPE.handleRequest(exchange);
    }

    // Prevent CSRF which can occur from standard a multipart/form-data submission from a standard
    // HTML form.
    // If the browser sends an Origin header (Chrome / Webkit) then the earlier origin check will
    // have passed
    // to reach this point. If the browser doesn't (FireFox), then  only requests which came from
    // Javascript,
    // which enforces same-origin policy when no Origin header is present, should be allowed. The
    // presence of
    // a custom header indicates usage of XHR since simple forms can not set them.
    HeaderMap headers = exchange.getRequestHeaders();
    if (!headers.contains(Headers.ORIGIN) && !headers.contains(CLIENT_NAME)) {
      ROOT_LOGGER.debug(
          "HTTP Origin or X-Management-Client-Name header is required for all multipart form data posts.");
      Common.UNAUTHORIZED.handleRequest(exchange);
      return;
    }

    // Parse the form data
    final FormData data = parser.parseBlocking();
    final OperationParameter.Builder operationParameterBuilder =
        new OperationParameter.Builder(false);

    // Process the operation
    final FormData.FormValue op = data.getFirst(OPERATION);
    final ModelNode operation;
    try {
      String type = op.getHeaders().getFirst(Headers.CONTENT_TYPE);
      if (Common.APPLICATION_DMR_ENCODED.equals(type)) {
        try (InputStream stream = convertToStream(op)) {
          operation = ModelNode.fromBase64(stream);
        }
        operationParameterBuilder.encode(true);
      } else if (Common.APPLICATION_JSON.equals(stripSuffix(type))) {
        try (InputStream stream = convertToStream(op)) {
          operation = ModelNode.fromJSONStream(stream);
        }
      } else {
        ROOT_LOGGER.debug("Content-type must be application/dmr-encoded or application/json");
        Common.UNAUTHORIZED.handleRequest(exchange);
        return;
      }
    } catch (Exception e) {
      ROOT_LOGGER.errorf("Unable to construct ModelNode '%s'", e.getMessage());
      Common.sendError(exchange, false, e.getLocalizedMessage());
      return;
    }

    // Process the input streams
    final OperationBuilder builder = OperationBuilder.create(operation, true);
    final Iterator<String> i = data.iterator();
    while (i.hasNext()) {
      final String name = i.next();
      final Deque<FormData.FormValue> contents = data.get(name);
      if (contents != null && !contents.isEmpty()) {
        for (final FormData.FormValue value : contents) {
          if (value.isFile()) {
            builder.addFileAsAttachment(value.getPath().toFile());
          }
        }
      }
    }

    operationParameterBuilder.pretty(
        operation.hasDefined("json.pretty") && operation.get("json.pretty").asBoolean());
    // Response callback to handle the :reload operation
    final OperationParameter opParam = operationParameterBuilder.build();
    final ResponseCallback callback =
        new ResponseCallback() {
          @Override
          void doSendResponse(final ModelNode response) {
            if (response.hasDefined(OUTCOME) && FAILED.equals(response.get(OUTCOME).asString())) {
              Common.sendError(exchange, opParam.isEncode(), response);
              return;
            }
            writeResponse(exchange, 200, response, opParam);
          }
        };

    final boolean sendPreparedResponse = sendPreparedResponse(operation);
    final ModelController.OperationTransactionControl control =
        sendPreparedResponse
            ? new ModelController.OperationTransactionControl() {
              @Override
              public void operationPrepared(
                  final ModelController.OperationTransaction transaction, final ModelNode result) {
                transaction.commit();
                // Fix prepared result
                result.get(OUTCOME).set(SUCCESS);
                result.get(RESULT);
                callback.sendResponse(result);
              }
            }
            : ModelController.OperationTransactionControl.COMMIT;

    ModelNode response;
    final Operation builtOp = builder.build();
    try {
      ModelNode opheaders = operation.get(OPERATION_HEADERS);
      opheaders.get(ACCESS_MECHANISM).set(AccessMechanism.HTTP.toString());
      opheaders.get(CALLER_TYPE).set(USER);
      // Don't allow a domain-uuid operation header from a user call
      if (opheaders.hasDefined(DOMAIN_UUID)) {
        opheaders.remove(DOMAIN_UUID);
      }
      response =
          modelController.execute(operation, OperationMessageHandler.DISCARD, control, builtOp);
    } catch (Throwable t) {
      ROOT_LOGGER.modelRequestError(t);
      Common.sendError(exchange, opParam.isEncode(), t.getLocalizedMessage());
      return;
    } finally {
      // Close any input streams that were open
      if (builtOp.isAutoCloseStreams()) {
        for (InputStream in : builtOp.getInputStreams()) {
          IoUtils.safeClose(in);
        }
      }
    }

    callback.sendResponse(response);
  }
  private HttpHandler setupSecurityHandlers(HttpHandler initialHandler) {
    final DeploymentInfo deploymentInfo = super.getDeployment().getDeploymentInfo();
    final LoginConfig loginConfig = deploymentInfo.getLoginConfig();

    final Map<String, AuthenticationMechanismFactory> factoryMap =
        new HashMap<>(deploymentInfo.getAuthenticationMechanisms());
    if (!factoryMap.containsKey(BASIC_AUTH)) {
      factoryMap.put(BASIC_AUTH, BasicAuthenticationMechanism.FACTORY);
    }
    if (!factoryMap.containsKey(FORM_AUTH)) {
      factoryMap.put(FORM_AUTH, ServletFormAuthenticationMechanism.FACTORY);
    }
    if (!factoryMap.containsKey(DIGEST_AUTH)) {
      factoryMap.put(DIGEST_AUTH, DigestAuthenticationMechanism.FACTORY);
    }
    if (!factoryMap.containsKey(CLIENT_CERT_AUTH)) {
      factoryMap.put(CLIENT_CERT_AUTH, ClientCertAuthenticationMechanism.FACTORY);
    }
    if (!factoryMap.containsKey(ExternalAuthenticationMechanism.NAME)) {
      factoryMap.put(ExternalAuthenticationMechanism.NAME, ExternalAuthenticationMechanism.FACTORY);
    }
    HttpHandler current = initialHandler;
    current = new SSLInformationAssociationHandler(current);

    final SecurityPathMatches securityPathMatches = buildSecurityConstraints();
    current = new ServletAuthenticationCallHandler(current);
    if (deploymentInfo.isDisableCachingForSecuredPages()) {
      current =
          Handlers.predicate(Predicates.authRequired(), Handlers.disableCache(current), current);
    }
    if (!securityPathMatches.isEmpty()) {
      current = new ServletAuthenticationConstraintHandler(current);
    }
    current =
        new ServletConfidentialityConstraintHandler(
            deploymentInfo.getConfidentialPortManager(), current);
    if (!securityPathMatches.isEmpty()) {
      current = new ServletSecurityConstraintHandler(securityPathMatches, current);
    }
    List<AuthenticationMechanism> authenticationMechanisms = new LinkedList<>();
    authenticationMechanisms.add(
        new CachedAuthenticatedSessionMechanism()); // TODO: does this really need to be hard coded?

    String mechName = null;
    if (loginConfig != null || deploymentInfo.getJaspiAuthenticationMechanism() != null) {

      // we don't allow multipart requests, and always use the default encoding
      FormParserFactory parser =
          FormParserFactory.builder(false)
              .addParser(
                  new FormEncodedDataDefinition()
                      .setDefaultEncoding(deploymentInfo.getDefaultEncoding()))
              .build();

      List<AuthMethodConfig> authMethods = Collections.<AuthMethodConfig>emptyList();
      if (loginConfig != null) {
        authMethods = loginConfig.getAuthMethods();
      }

      for (AuthMethodConfig method : authMethods) {
        AuthenticationMechanismFactory factory = factoryMap.get(method.getName());
        if (factory == null) {
          throw UndertowServletMessages.MESSAGES.unknownAuthenticationMechanism(method.getName());
        }
        if (mechName == null) {
          mechName = method.getName();
        }

        final Map<String, String> properties = new HashMap<>();
        properties.put(
            AuthenticationMechanismFactory.CONTEXT_PATH, deploymentInfo.getContextPath());
        properties.put(AuthenticationMechanismFactory.REALM, loginConfig.getRealmName());
        properties.put(AuthenticationMechanismFactory.ERROR_PAGE, loginConfig.getErrorPage());
        properties.put(AuthenticationMechanismFactory.LOGIN_PAGE, loginConfig.getLoginPage());
        properties.putAll(method.getProperties());

        String name = method.getName().toUpperCase(Locale.US);
        // The mechanism name is passed in from the HttpServletRequest interface as the name
        // reported needs to be
        // comparable using '=='
        name = name.equals(FORM_AUTH) ? FORM_AUTH : name;
        name = name.equals(BASIC_AUTH) ? BASIC_AUTH : name;
        name = name.equals(DIGEST_AUTH) ? DIGEST_AUTH : name;
        name = name.equals(CLIENT_CERT_AUTH) ? CLIENT_CERT_AUTH : name;

        authenticationMechanisms.add(factory.create(name, parser, properties));
      }
    }

    ((DeploymentImpl) super.getDeployment()).setAuthenticationMechanisms(authenticationMechanisms);
    // if the JASPI auth mechanism is set then it takes over
    if (deploymentInfo.getJaspiAuthenticationMechanism() == null) {
      current = new AuthenticationMechanismsHandler(current, authenticationMechanisms);
    } else {
      current =
          new AuthenticationMechanismsHandler(
              current,
              Collections.<AuthenticationMechanism>singletonList(
                  deploymentInfo.getJaspiAuthenticationMechanism()));
    }

    current =
        new CachedAuthenticatedSessionHandler(current, super.getDeployment().getServletContext());
    List<NotificationReceiver> notificationReceivers = deploymentInfo.getNotificationReceivers();
    if (!notificationReceivers.isEmpty()) {
      current = new NotificationReceiverHandler(current, notificationReceivers);
    }

    // TODO - A switch to constraint driven could be configurable, however before we can support
    // that with servlets we would
    // need additional tracking within sessions if a servlet has specifically requested that
    // authentication occurs.
    SecurityContextFactory contextFactory = deploymentInfo.getSecurityContextFactory();
    if (contextFactory == null) {
      contextFactory = SecurityContextFactoryImpl.INSTANCE;
    }
    current =
        new SecurityInitialHandler(
            AuthenticationMode.PRO_ACTIVE,
            deploymentInfo.getIdentityManager(),
            mechName,
            contextFactory,
            current);
    return current;
  }
 public DomainApiGenericOperationHandler(ModelController modelController) {
   this.modelController = modelController;
   this.formParserFactory = FormParserFactory.builder().build();
 }