// Path: grpc-mate-java/elasticsearch-service/src/main/java/io/datanerd/es/guice/ElasticSearchModule.java
// public class ElasticSearchModule extends AbstractModule {
// 
//   @Override
//   protected void configure() {
//     bind(Configuration.class).toProvider(ConfigurationProvider.class).in(Singleton.class);
//     bind(TransportClient.class).toProvider(TransportClientProvider.class).in(Singleton.class);
//     bind(JsonFormat.Printer.class).toInstance(JsonFormat.printer());
//     bind(JsonFormat.Parser.class).toInstance(JsonFormat.parser());
//   }
// }
// 
// Path: grpc-mate-java/elasticsearch-service/src/main/java/io/datanerd/es/dao/ProductDao.java
// public static final String INDEX = "products";
// 
// Path: grpc-mate-java/elasticsearch-service/src/main/java/io/datanerd/es/dao/ProductDao.java
// public static final String TYPE = "Product";


import com.google.common.collect.Lists;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.util.Modules;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.util.JsonFormat;
import com.github.javafaker.Faker;
import org.apache.commons.configuration2.Configuration;
import org.apache.commons.configuration2.MapConfiguration;
import org.elasticsearch.action.admin.cluster.stats.ClusterStatsResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.transport.TransportClient;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.GenericContainer;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import io.datanerd.es.guice.ElasticSearchModule;
import io.datanerd.generated.common.Product;
import io.datanerd.generated.common.ProductStatus;
import io.datanerd.generated.es.CalculateProductScoreResponse;
import io.datanerd.generated.es.DownloadProductsRequest;
import io.datanerd.generated.es.SearchProductsRequest;
import io.datanerd.generated.es.SearchProductsResponse;
import io.reactivex.disposables.Disposable;
import io.reactivex.subjects.PublishSubject;
import static io.datanerd.es.TestConstant.ES_TEST_IMAGE;
import static io.datanerd.es.dao.ProductDao.INDEX;
import static io.datanerd.es.dao.ProductDao.TYPE;
import static io.datanerd.es.guice.Constants.CONFIG_ES_CLUSTER_HOST;
import static io.datanerd.es.guice.Constants.CONFIG_ES_CLUSTER_NAME;
import static io.datanerd.es.guice.Constants.CONFIG_ES_CLUSTER_PORT;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Fail.fail;
  @BeforeClass
  public static void setUpClass() throws Exception {
    faker = new Faker();
    String ip = esContainer.getContainerIpAddress();
    Integer transportPort = esContainer.getMappedPort(9300);
    MapConfiguration memoryParams = new MapConfiguration(new HashMap<>());
    memoryParams.setProperty(CONFIG_ES_CLUSTER_HOST, ip);
    memoryParams.setProperty(CONFIG_ES_CLUSTER_PORT, transportPort);
    memoryParams.setProperty(CONFIG_ES_CLUSTER_NAME, "elasticsearch");
    injector = Guice.createInjector(
        Modules.override(new ElasticSearchModule())
            .with(binder -> {
              binder.bind(Configuration.class).toProvider(() -> memoryParams);
            })
    );
    productDao = injector.getInstance(ProductDao.class);
    esClient = injector.getInstance(TransportClient.class);
  }

  @Before
  public void setUp() throws Exception {
    productDao.initIndexIfNotExists();
  }

  @After
  public void tearDown() throws Exception {
    ClusterStatsResponse clusterStatsResponse = esClient.admin().cluster().prepareClusterStats().get();
    //be sure it's for unit test clean up
    if (clusterStatsResponse.getClusterName().value().equals("elasticsearch")
        && clusterStatsResponse.getNodes().size() == 1) {
// Path: grpc-mate-java/elasticsearch-service/src/main/java/io/datanerd/es/guice/ElasticSearchModule.java
// public class ElasticSearchModule extends AbstractModule {
// 
//   @Override
//   protected void configure() {
//     bind(Configuration.class).toProvider(ConfigurationProvider.class).in(Singleton.class);
//     bind(TransportClient.class).toProvider(TransportClientProvider.class).in(Singleton.class);
//     bind(JsonFormat.Printer.class).toInstance(JsonFormat.printer());
//     bind(JsonFormat.Parser.class).toInstance(JsonFormat.parser());
//   }
// }
// 
// Path: grpc-mate-java/elasticsearch-service/src/main/java/io/datanerd/es/dao/ProductDao.java
// public static final String INDEX = "products";
// 
// Path: grpc-mate-java/elasticsearch-service/src/main/java/io/datanerd/es/dao/ProductDao.java
// public static final String TYPE = "Product";


// Path: grpc-mate-java/elasticsearch-service/src/test/java/io/datanerd/es/dao/ProductDaoTest.java
import com.google.common.collect.Lists;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.util.Modules;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.util.JsonFormat;
import com.github.javafaker.Faker;
import org.apache.commons.configuration2.Configuration;
import org.apache.commons.configuration2.MapConfiguration;
import org.elasticsearch.action.admin.cluster.stats.ClusterStatsResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.transport.TransportClient;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.GenericContainer;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import io.datanerd.es.guice.ElasticSearchModule;
import io.datanerd.generated.common.Product;
import io.datanerd.generated.common.ProductStatus;
import io.datanerd.generated.es.CalculateProductScoreResponse;
import io.datanerd.generated.es.DownloadProductsRequest;
import io.datanerd.generated.es.SearchProductsRequest;
import io.datanerd.generated.es.SearchProductsResponse;
import io.reactivex.disposables.Disposable;
import io.reactivex.subjects.PublishSubject;
import static io.datanerd.es.TestConstant.ES_TEST_IMAGE;
import static io.datanerd.es.dao.ProductDao.INDEX;
import static io.datanerd.es.dao.ProductDao.TYPE;
import static io.datanerd.es.guice.Constants.CONFIG_ES_CLUSTER_HOST;
import static io.datanerd.es.guice.Constants.CONFIG_ES_CLUSTER_NAME;
import static io.datanerd.es.guice.Constants.CONFIG_ES_CLUSTER_PORT;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Fail.fail;

  @BeforeClass
  public static void setUpClass() throws Exception {
    faker = new Faker();
    String ip = esContainer.getContainerIpAddress();
    Integer transportPort = esContainer.getMappedPort(9300);
    MapConfiguration memoryParams = new MapConfiguration(new HashMap<>());
    memoryParams.setProperty(CONFIG_ES_CLUSTER_HOST, ip);
    memoryParams.setProperty(CONFIG_ES_CLUSTER_PORT, transportPort);
    memoryParams.setProperty(CONFIG_ES_CLUSTER_NAME, "elasticsearch");
    injector = Guice.createInjector(
        Modules.override(new ElasticSearchModule())
            .with(binder -> {
              binder.bind(Configuration.class).toProvider(() -> memoryParams);
            })
    );
    productDao = injector.getInstance(ProductDao.class);
    esClient = injector.getInstance(TransportClient.class);
  }

  @Before
  public void setUp() throws Exception {
    productDao.initIndexIfNotExists();
  }

  @After
  public void tearDown() throws Exception {
    ClusterStatsResponse clusterStatsResponse = esClient.admin().cluster().prepareClusterStats().get();
    //be sure it's for unit test clean up
    if (clusterStatsResponse.getClusterName().value().equals("elasticsearch")
        && clusterStatsResponse.getNodes().size() == 1) {
      esClient.admin().indices().delete(new DeleteIndexRequest(INDEX)).actionGet();