/** @throws Exception If failed. */
  public void testClientAffinity() throws Exception {
    GridClientData partitioned = client.data(PARTITIONED_CACHE_NAME);

    Collection<Object> keys = new ArrayList<>();

    keys.addAll(Arrays.asList(Boolean.TRUE, Boolean.FALSE, 1, Integer.MAX_VALUE));

    Random rnd = new Random();
    StringBuilder sb = new StringBuilder();

    // Generate some random strings.
    for (int i = 0; i < 100; i++) {
      sb.setLength(0);

      for (int j = 0; j < 255; j++)
        // Only printable ASCII symbols for test.
        sb.append((char) (rnd.nextInt(0x7f - 0x20) + 0x20));

      keys.add(sb.toString());
    }

    // Generate some more keys to achieve better coverage.
    for (int i = 0; i < 100; i++) keys.add(UUID.randomUUID());

    for (Object key : keys) {
      UUID nodeId = grid(0).mapKeyToNode(PARTITIONED_CACHE_NAME, key).id();

      UUID clientNodeId = partitioned.affinity(key);

      assertEquals(
          "Invalid affinity mapping for REST response for key: " + key, nodeId, clientNodeId);
    }
  }
  /**
   * Streams random prices into the system.
   *
   * @param g Grid.
   * @throws GridException If failed.
   */
  private static void streamData(final Grid g) throws GridException {
    GridStreamer streamer = g.streamer("priceBars");

    for (int i = 0; i < CNT; i++) {
      for (int j = 0; j < INSTRUMENTS.length; j++) {
        // Use gaussian distribution to ensure that
        // numbers closer to 0 have higher probability.
        double price = round2(INITIAL_PRICES[j] + RAND.nextGaussian());

        Quote quote = new Quote(INSTRUMENTS[j], price);

        streamer.addEvent(quote);
      }
    }
  }
  /**
   * @param args Command arguments.
   * @throws GridException If failed.
   */
  public static void main(String[] args) throws GridException {
    // Starts grid.
    Grid grid = args.length == 0 ? G.start() : G.start(args[0]);

    try {
      // Create portfolio.
      GridCredit[] portfolio = new GridCredit[5000];

      Random rnd = new Random();

      // Generate some test portfolio items.
      for (int i = 0; i < portfolio.length; i++) {
        portfolio[i] =
            new GridCredit(
                50000 * rnd.nextDouble(), // Credit amount.
                rnd.nextInt(1000), // Credit term in days.
                rnd.nextDouble() / 10, // APR.
                rnd.nextDouble() / 20 + 0.02 // EDF.
                );
      }

      // Forecast horizon in days.
      int horizon = 365;

      // Number of Monte-Carlo iterations.
      int iter = 10000;

      // Percentile.
      double percentile = 0.95;

      // Mark the stopwatch.
      long start = System.currentTimeMillis();

      // Calculate credit risk and print it out.
      // As you can see the grid enabling is completely hidden from the caller
      // and it is fully transparent to him. In fact, the caller is never directly
      // aware if method was executed just locally or on the 100s of grid nodes.
      // Credit risk crdRisk is the minimal amount that creditor has to have
      // available to cover possible defaults.
      double crdRisk =
          grid.reduce(
              SPREAD,
              closures(grid.size(), portfolio, horizon, iter, percentile),
              new R1<Double, Double>() {
                /** Collected values sum. */
                private double sum;

                /** Collected values count. */
                private int count;

                /** {@inheritDoc} */
                @Override
                public boolean collect(Double e) {
                  sum += e;
                  count++;

                  return true;
                }

                /** {@inheritDoc} */
                @Override
                public Double apply() {
                  return sum / count;
                }
              });

      X.println(
          "Credit risk [crdRisk="
              + crdRisk
              + ", duration="
              + (System.currentTimeMillis() - start)
              + "ms]");
    }
    // We specifically don't do any error handling here to
    // simplify the example. Real application may want to
    // add error handling and application specific recovery.
    finally {
      // Stops grid.
      G.stop(true);
    }
  }