/**
   * Parses HTTP parameters in an appropriate format and return back map of values to predefined
   * list of names.
   *
   * @param req Request.
   * @return Map of parsed parameters.
   */
  @SuppressWarnings({"unchecked"})
  private Map<String, Object> parameters(ServletRequest req) {
    Map<String, String[]> params = req.getParameterMap();

    if (F.isEmpty(params)) return Collections.emptyMap();

    Map<String, Object> map = U.newHashMap(params.size());

    for (Map.Entry<String, String[]> entry : params.entrySet())
      map.put(entry.getKey(), parameter(entry.getValue()));

    return map;
  }
  /**
   * Gets values referenced by sequential keys, e.g. {@code key1...keyN}.
   *
   * @param keyPrefix Key prefix, e.g. {@code key} for {@code key1...keyN}.
   * @param params Parameters map.
   * @return Values.
   */
  @Nullable
  protected List<Object> values(String keyPrefix, Map<String, Object> params) {
    assert keyPrefix != null;

    List<Object> vals = new LinkedList<>();

    for (int i = 1; ; i++) {
      String key = keyPrefix + i;

      if (params.containsKey(key)) vals.add(params.get(key));
      else break;
    }

    return vals;
  }
  /** {@inheritDoc} */
  @Override
  public Map<? extends GridComputeJob, GridNode> map(List<GridNode> subgrid, Integer arg)
      throws GridException {
    assert taskSes != null;
    assert arg != null;
    assert arg > 0;

    Map<GridSessionLoadTestJob, GridNode> map = new HashMap<>(subgrid.size());

    Iterator<GridNode> iter = subgrid.iterator();

    Random rnd = new Random();

    params = new HashMap<>(arg);

    Collection<UUID> assigned = new ArrayList<>(subgrid.size());

    for (int i = 0; i < arg; i++) {
      // Recycle iterator.
      if (!iter.hasNext()) iter = subgrid.iterator();

      String paramName = UUID.randomUUID().toString();

      int paramVal = rnd.nextInt();

      taskSes.setAttribute(paramName, paramVal);

      GridNode node = iter.next();

      assigned.add(node.id());

      map.put(new GridSessionLoadTestJob(paramName), node);

      params.put(paramName, paramVal);

      if (log.isDebugEnabled())
        log.debug("Set session attribute [name=" + paramName + ", value=" + paramVal + ']');
    }

    taskSes.setAttribute("nodes", assigned);

    return map;
  }
  /**
   * Retrieves UUID value from parameters map.
   *
   * @param key Key.
   * @param params Parameters map.
   * @return UUID value from parameters map or {@code null} if null or not exists.
   * @throws GridException If parsing failed.
   */
  @Nullable
  private static UUID uuidValue(String key, Map<String, Object> params) throws GridException {
    assert key != null;

    String val = (String) params.get(key);

    try {
      return val == null ? null : UUID.fromString(val);
    } catch (NumberFormatException ignore) {
      throw new GridException("Failed to parse parameter of UUID type [" + key + "=" + val + "]");
    }
  }
  /**
   * Retrieves long value from parameters map.
   *
   * @param key Key.
   * @param params Parameters map.
   * @param dfltVal Default value.
   * @return Long value from parameters map or {@code dfltVal} if null or not exists.
   * @throws GridException If parsing failed.
   */
  @Nullable
  private static Long longValue(String key, Map<String, Object> params, Long dfltVal)
      throws GridException {
    assert key != null;

    String val = (String) params.get(key);

    try {
      return val == null ? dfltVal : Long.valueOf(val);
    } catch (NumberFormatException ignore) {
      throw new GridException("Failed to parse parameter of Long type [" + key + "=" + val + "]");
    }
  }
  /** {@inheritDoc} */
  @SuppressWarnings("BusyWait")
  @Override
  public Boolean reduce(List<GridComputeJobResult> results) throws GridException {
    assert taskSes != null;
    assert results != null;
    assert params != null;
    assert !params.isEmpty();
    assert results.size() == params.size();

    Map<String, Integer> receivedParams = new HashMap<>();

    boolean allAttrReceived = false;

    int cnt = 0;

    while (!allAttrReceived && cnt++ < 3) {
      allAttrReceived = true;

      for (Map.Entry<String, Integer> entry : params.entrySet()) {
        assert taskSes.getAttribute(entry.getKey()) != null;

        Integer newVal = (Integer) taskSes.getAttribute(entry.getKey());

        assert newVal != null;

        receivedParams.put(entry.getKey(), newVal);

        if (newVal != entry.getValue() + 1) allAttrReceived = false;
      }

      if (!allAttrReceived) {
        try {
          Thread.sleep(100);
        } catch (InterruptedException e) {
          throw new GridException("Thread interrupted.", e);
        }
      }
    }

    if (log.isDebugEnabled()) {
      for (Map.Entry<String, Integer> entry : receivedParams.entrySet()) {
        log.debug(
            "Received session attr value [name="
                + entry.getKey()
                + ", val="
                + entry.getValue()
                + ", expected="
                + (params.get(entry.getKey()) + 1)
                + ']');
      }
    }

    return allAttrReceived;
  }
  /**
   * @param cctx Context.
   * @param tx Transaction.
   * @param failedNodeId ID of failed node started transaction.
   */
  @SuppressWarnings("ConstantConditions")
  public GridCachePessimisticCheckCommittedTxFuture(
      GridCacheContext<K, V> cctx, GridCacheTxEx<K, V> tx, UUID failedNodeId) {
    super(cctx.kernalContext(), new SingleReducer<K, V>());

    this.cctx = cctx;
    this.tx = tx;
    this.failedNodeId = failedNodeId;

    log = U.logger(ctx, logRef, GridCacheOptimisticCheckPreparedTxFuture.class);

    nodes = new GridLeanMap<>();

    for (GridNode node : CU.allNodes(cctx, tx.topologyVersion())) nodes.put(node.id(), node);
  }
  /**
   * Creates REST request.
   *
   * @param cmd Command.
   * @param params Parameters.
   * @return REST request.
   * @throws GridException If creation failed.
   */
  @Nullable
  private GridRestRequest createRequest(
      GridRestCommand cmd, Map<String, Object> params, ServletRequest req) throws GridException {
    GridRestRequest restReq;

    switch (cmd) {
      case CACHE_GET:
      case CACHE_GET_ALL:
      case CACHE_PUT:
      case CACHE_PUT_ALL:
      case CACHE_REMOVE:
      case CACHE_REMOVE_ALL:
      case CACHE_ADD:
      case CACHE_CAS:
      case CACHE_METRICS:
      case CACHE_REPLACE:
      case CACHE_DECREMENT:
      case CACHE_INCREMENT:
      case CACHE_APPEND:
      case CACHE_PREPEND:
        {
          GridRestCacheRequest restReq0 = new GridRestCacheRequest();

          restReq0.cacheName((String) params.get("cacheName"));
          restReq0.key(params.get("key"));
          restReq0.value(params.get("val"));
          restReq0.value2(params.get("val2"));

          Object val1 = params.get("val1");

          if (val1 != null) restReq0.value(val1);

          restReq0.cacheFlags(intValue("cacheFlags", params, 0));
          restReq0.ttl(longValue("exp", params, null));
          restReq0.initial(longValue("init", params, null));
          restReq0.delta(longValue("delta", params, null));

          if (cmd == CACHE_GET_ALL || cmd == CACHE_PUT_ALL || cmd == CACHE_REMOVE_ALL) {
            List<Object> keys = values("k", params);
            List<Object> vals = values("v", params);

            if (keys.size() < vals.size())
              throw new GridException(
                  "Number of keys must be greater or equals to number of values.");

            Map<Object, Object> map = U.newHashMap(keys.size());

            Iterator<Object> keyIt = keys.iterator();
            Iterator<Object> valIt = vals.iterator();

            while (keyIt.hasNext()) map.put(keyIt.next(), valIt.hasNext() ? valIt.next() : null);

            restReq0.values(map);
          }

          restReq = restReq0;

          break;
        }

      case TOPOLOGY:
      case NODE:
        {
          GridRestTopologyRequest restReq0 = new GridRestTopologyRequest();

          restReq0.includeMetrics(Boolean.parseBoolean((String) params.get("mtr")));
          restReq0.includeAttributes(Boolean.parseBoolean((String) params.get("attr")));

          restReq0.nodeIp((String) params.get("ip"));

          restReq0.nodeId(uuidValue("id", params));

          restReq = restReq0;

          break;
        }

      case EXE:
      case RESULT:
      case NOOP:
        {
          GridRestTaskRequest restReq0 = new GridRestTaskRequest();

          restReq0.taskId((String) params.get("id"));
          restReq0.taskName((String) params.get("name"));

          restReq0.params(values("p", params));

          restReq0.async(Boolean.parseBoolean((String) params.get("async")));

          restReq0.timeout(longValue("timeout", params, 0L));

          restReq = restReq0;

          break;
        }

      case LOG:
        {
          GridRestLogRequest restReq0 = new GridRestLogRequest();

          restReq0.path((String) params.get("path"));

          restReq0.from(intValue("from", params, -1));
          restReq0.to(intValue("to", params, -1));

          restReq = restReq0;

          break;
        }

      case VERSION:
        {
          restReq = new GridRestRequest();

          break;
        }

      default:
        throw new GridException("Invalid command: " + cmd);
    }

    restReq.address(new InetSocketAddress(req.getRemoteAddr(), req.getRemotePort()));

    restReq.command(cmd);

    if (params.containsKey("gridgain.login") || params.containsKey("gridgain.password")) {
      GridSecurityCredentials cred =
          new GridSecurityCredentials(
              (String) params.get("gridgain.login"), (String) params.get("gridgain.password"));

      restReq.credentials(cred);
    }

    String clientId = (String) params.get("clientId");

    try {
      if (clientId != null) restReq.clientId(UUID.fromString(clientId));
    } catch (Exception ignored) {
      // Ignore invalid client id. Rest handler will process this logic.
    }

    String destId = (String) params.get("destId");

    try {
      if (destId != null) restReq.destinationId(UUID.fromString(destId));
    } catch (IllegalArgumentException ignored) {
      // Don't fail - try to execute locally.
    }

    String sesTokStr = (String) params.get("sessionToken");

    try {
      if (sesTokStr != null) restReq.sessionToken(U.hexString2ByteArray(sesTokStr));
    } catch (IllegalArgumentException ignored) {
      // Ignore invalid session token.
    }

    return restReq;
  }
  /** {@inheritDoc} */
  @Override
  public GridFuture<?> addData(Map<K, V> entries) throws IllegalStateException {
    A.notNull(entries, "entries");

    return addData(entries.entrySet());
  }
  /**
   * See <a href="http://e-docs.bea.com/wls/docs100/javadocs/weblogic/common/T3StartupDef.html">
   * http://e-docs.bea.com/wls/docs100/javadocs/weblogic/common/T3StartupDef.html</a> for more
   * information.
   *
   * @param str Virtual name by which the class is registered as a {@code startupClass} in the
   *     {@code config.xml} file
   * @param params A hashtable that is made up of the name-value pairs supplied from the {@code
   *     startupArgs} property
   * @return Result string (log message).
   * @throws Exception Thrown if error occurred.
   */
  @SuppressWarnings({"unchecked", "CatchGenericClass"})
  @Override
  public String startup(String str, Hashtable params) throws Exception {
    GridLogger log = new GridJavaLogger(LoggingHelper.getServerLogger());

    cfgFile = (String) params.get(cfgFilePathParam);

    if (cfgFile == null) {
      throw new IllegalArgumentException("Failed to read property: " + cfgFilePathParam);
    }

    String workMgrName = (String) params.get(workMgrParam);

    URL cfgUrl = U.resolveGridGainUrl(cfgFile);

    if (cfgUrl == null)
      throw new ServerLifecycleException(
          "Failed to find Spring configuration file (path provided should be "
              + "either absolute, relative to GRIDGAIN_HOME, or relative to META-INF folder): "
              + cfgFile);

    GenericApplicationContext springCtx;

    try {
      springCtx = new GenericApplicationContext();

      XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(springCtx);

      xmlReader.loadBeanDefinitions(new UrlResource(cfgUrl));

      springCtx.refresh();
    } catch (BeansException e) {
      throw new ServerLifecycleException(
          "Failed to instantiate Spring XML application context: " + e.getMessage(), e);
    }

    Map cfgMap;

    try {
      // Note: Spring is not generics-friendly.
      cfgMap = springCtx.getBeansOfType(GridConfiguration.class);
    } catch (BeansException e) {
      throw new ServerLifecycleException(
          "Failed to instantiate bean [type="
              + GridConfiguration.class
              + ", err="
              + e.getMessage()
              + ']',
          e);
    }

    if (cfgMap == null)
      throw new ServerLifecycleException(
          "Failed to find a single grid factory configuration in: " + cfgUrl);

    if (cfgMap.isEmpty())
      throw new ServerLifecycleException("Can't find grid factory configuration in: " + cfgUrl);

    try {
      ExecutorService execSvc = null;

      MBeanServer mbeanSrv = null;

      for (GridConfiguration cfg : (Collection<GridConfiguration>) cfgMap.values()) {
        assert cfg != null;

        GridConfigurationAdapter adapter = new GridConfigurationAdapter(cfg);

        // Set logger.
        if (cfg.getGridLogger() == null) adapter.setGridLogger(log);

        if (cfg.getExecutorService() == null) {
          if (execSvc == null)
            execSvc =
                workMgrName != null
                    ? new GridThreadWorkManagerExecutor(workMgrName)
                    : new GridThreadWorkManagerExecutor(J2EEWorkManager.getDefault());

          adapter.setExecutorService(execSvc);
        }

        if (cfg.getMBeanServer() == null) {
          if (mbeanSrv == null) {
            InitialContext ctx = null;

            try {
              ctx = new InitialContext();

              mbeanSrv = (MBeanServer) ctx.lookup("java:comp/jmx/runtime");
            } catch (Exception e) {
              throw new IllegalArgumentException(
                  "MBean server was not provided and failed to obtain " + "Weblogic MBean server.",
                  e);
            } finally {
              if (ctx != null) ctx.close();
            }
          }

          adapter.setMBeanServer(mbeanSrv);
        }

        Grid grid = G.start(adapter, springCtx);

        // Test if grid is not null - started properly.
        if (grid != null) gridNames.add(grid.name());
      }

      return getClass().getSimpleName() + " started successfully.";
    } catch (GridException e) {
      // Stop started grids only.
      for (String name : gridNames) G.stop(name, true);

      throw new ServerLifecycleException("Failed to start GridGain.", e);
    }
  }
 /** {@inheritDoc} */
 @Override
 public Collection<? extends GridNode> nodes() {
   return nodes.values();
 }