All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.flowthings.client.api.MockRestApi Maven / Gradle / Ivy

There is a newer version: 0.9.3.2
Show newest version
package com.flowthings.client.api;

import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;

import com.flowthings.client.Credentials;
import com.flowthings.client.exception.FlowthingsException;
import com.google.common.util.concurrent.SettableFuture;

/**
 * A utility class for testing the behaviour of a REST connection. No actual
 * connection is made - it is faked This class has two purposes:
 *
 * 1) You can supply responses to requests you make 2) You can simulate
 * disconnections
 *
 * Created by matt on 7/6/16.
 */
public class MockRestApi extends RestApi {
  private ConcurrentHashMap answers = new ConcurrentHashMap<>();
  private ConcurrentHashMap counters = new ConcurrentHashMap<>();
  private ExecutorService pool = Executors.newCachedThreadPool();

  public MockRestApi() throws FlowthingsException {
    super(new Credentials("a", "b"));
  }

  public MockRestApi setAnswer(Request request, Callable response) {
    answers.put(request, response);
    return this;
  }

  public MockRestApi setAnswers(Request request, Object... responses) {
    final AtomicInteger counter = new AtomicInteger();
    answers.put(request, () -> {
      int i = counter.getAndIncrement();
      i = Math.min(responses.length - 1, i);
      Object response = responses[i];
      if (response instanceof FlowthingsException) {
        throw (FlowthingsException) response;
      }
      return response;
    });
    return this;
  }

  public MockRestApi setException(Request request, FlowthingsException response) {
    answers.put(request, () -> {
      throw response;
    });
    return this;
  }

  public MockRestApi setAnswerImmediately(Request request, Object response) {
    answers.put(request, () -> response);
    return this;
  }

  @Override
  public  FlowthingsFuture sendAsync(Request request) {
    final Callable provider = answers.get(request);
    // Increment counter
    counters.compute(request, (k, v) -> {
      if (v == null) {
        return new AtomicInteger(0);
      }
      v.incrementAndGet();
      return v;
    });
    if (provider != null) {
      Future future = pool.submit(provider);
      return new FlowthingsFuture<>(future);
    }
    // Block forever
    return new FlowthingsFuture<>(SettableFuture. create());
  }

  public int getCounter(Request request) {
    return counters.getOrDefault(request, new AtomicInteger(0)).get();
  }
}