@Before
  public void setupServices() {
    final Config full_config = ConfigFactory.empty();
    if (null == _connection_string) {
      _crud_factory = new MockElasticsearchCrudServiceFactory();
    } else {
      final ElasticsearchConfigurationBean config_bean =
          new ElasticsearchConfigurationBean(_connection_string, _cluster_name);
      _crud_factory = new ElasticsearchCrudServiceFactory(config_bean);
    }
    _config_bean = ElasticsearchIndexConfigUtils.buildConfigBean(full_config);

    _index_service = new MockElasticsearchIndexService(_crud_factory, _config_bean);
  }
  @Test
  public void test_indexCreation() throws IOException {

    final Calendar time_setter = GregorianCalendar.getInstance();
    time_setter.set(2015, 1, 1, 13, 0, 0);

    final String bucket_str =
        Resources.toString(
            Resources.getResource(
                "com/ikanow/aleph2/search_service/elasticsearch/services/test_bucket_validate_success.json"),
            Charsets.UTF_8);
    final DataBucketBean bucket =
        BeanTemplateUtils.build(bucket_str, DataBucketBean.class)
            .with("modified", time_setter.getTime())
            .done()
            .get();

    final String mapping_str =
        Resources.toString(
            Resources.getResource(
                "com/ikanow/aleph2/search_service/elasticsearch/services/test_verbose_mapping_validate_results.json"),
            Charsets.UTF_8);
    final JsonNode mapping_json = _mapper.readTree(mapping_str.getBytes());

    final String template_name = ElasticsearchIndexUtils.getBaseIndexName(bucket);

    try {
      _crud_factory
          .getClient()
          .admin()
          .indices()
          .prepareDeleteTemplate(template_name)
          .execute()
          .actionGet();
    } catch (Exception e) {
    } // (This is fine, just means it doesn't exist)

    // Create index template from empty

    {
      final GetIndexTemplatesRequest gt = new GetIndexTemplatesRequest().names(template_name);
      final GetIndexTemplatesResponse gtr =
          _crud_factory.getClient().admin().indices().getTemplates(gt).actionGet();
      assertTrue("No templates to start with", gtr.getIndexTemplates().isEmpty());

      _index_service.handlePotentiallyNewIndex(
          bucket,
          Optional.empty(),
          ElasticsearchIndexConfigUtils.buildConfigBeanFromSchema(bucket, _config_bean, _mapper),
          "_default_");

      final GetIndexTemplatesRequest gt2 = new GetIndexTemplatesRequest().names(template_name);
      final GetIndexTemplatesResponse gtr2 =
          _crud_factory.getClient().admin().indices().getTemplates(gt2).actionGet();
      assertEquals(1, _index_service._bucket_template_cache.size());
      assertEquals(1, gtr2.getIndexTemplates().size());

      assertTrue(
          "Mappings should be equivalent",
          ElasticsearchIndexService.mappingsAreEquivalent(
              gtr2.getIndexTemplates().get(0), mapping_json, _mapper));
    }

    // Check is ignored subsequently (same date, same content; same date, different content)
    {
      _index_service.handlePotentiallyNewIndex(
          bucket,
          Optional.empty(),
          ElasticsearchIndexConfigUtils.buildConfigBeanFromSchema(bucket, _config_bean, _mapper),
          "_default_");

      final GetIndexTemplatesRequest gt2 = new GetIndexTemplatesRequest().names(template_name);
      final GetIndexTemplatesResponse gtr2 =
          _crud_factory.getClient().admin().indices().getTemplates(gt2).actionGet();
      assertEquals(1, _index_service._bucket_template_cache.size());
      assertEquals(1, gtr2.getIndexTemplates().size());
    }

    // Check is checked-but-left if time updated, content not
    {
      time_setter.set(2015, 1, 1, 14, 0, 0);
      final Date next_time = time_setter.getTime();
      final DataBucketBean bucket2 =
          BeanTemplateUtils.clone(bucket).with("modified", next_time).done();

      _index_service.handlePotentiallyNewIndex(
          bucket2,
          Optional.empty(),
          ElasticsearchIndexConfigUtils.buildConfigBeanFromSchema(bucket2, _config_bean, _mapper),
          "_default_");

      final GetIndexTemplatesRequest gt2 = new GetIndexTemplatesRequest().names(template_name);
      final GetIndexTemplatesResponse gtr2 =
          _crud_factory.getClient().admin().indices().getTemplates(gt2).actionGet();
      assertEquals(1, _index_service._bucket_template_cache.size());
      assertEquals(next_time, _index_service._bucket_template_cache.get(bucket._id()));
      assertEquals(1, gtr2.getIndexTemplates().size());
    }

    // Check is updated if time-and-content is different
    {
      time_setter.set(2015, 1, 1, 15, 0, 0);
      final String bucket_str2 =
          Resources.toString(
              Resources.getResource(
                  "com/ikanow/aleph2/search_service/elasticsearch/services/test_bucket2_validate_success.json"),
              Charsets.UTF_8);
      final DataBucketBean bucket2 =
          BeanTemplateUtils.build(bucket_str2, DataBucketBean.class)
              .with("modified", time_setter.getTime())
              .done()
              .get();

      _index_service.handlePotentiallyNewIndex(
          bucket2,
          Optional.empty(),
          ElasticsearchIndexConfigUtils.buildConfigBeanFromSchema(bucket2, _config_bean, _mapper),
          "_default_");

      final GetIndexTemplatesRequest gt2 = new GetIndexTemplatesRequest().names(template_name);
      final GetIndexTemplatesResponse gtr2 =
          _crud_factory.getClient().admin().indices().getTemplates(gt2).actionGet();
      assertEquals(1, _index_service._bucket_template_cache.size());
      assertEquals(time_setter.getTime(), _index_service._bucket_template_cache.get(bucket._id()));
      assertEquals(1, gtr2.getIndexTemplates().size());

      assertFalse(
          ElasticsearchIndexService.mappingsAreEquivalent(
              gtr2.getIndexTemplates().get(0), mapping_json, _mapper)); // has changed
    }

    // Check if mapping is deleted then next time bucket modified is updated then the mapping is
    // recreated

    {
      _crud_factory
          .getClient()
          .admin()
          .indices()
          .prepareDeleteTemplate(template_name)
          .execute()
          .actionGet();

      // (check with old date)

      final GetIndexTemplatesRequest gt = new GetIndexTemplatesRequest().names(template_name);
      final GetIndexTemplatesResponse gtr =
          _crud_factory.getClient().admin().indices().getTemplates(gt).actionGet();
      assertTrue("No templates to start with", gtr.getIndexTemplates().isEmpty());

      {
        _index_service.handlePotentiallyNewIndex(
            bucket,
            Optional.empty(),
            ElasticsearchIndexConfigUtils.buildConfigBeanFromSchema(bucket, _config_bean, _mapper),
            "_default_");

        final GetIndexTemplatesRequest gt2 = new GetIndexTemplatesRequest().names(template_name);
        final GetIndexTemplatesResponse gtr2 =
            _crud_factory.getClient().admin().indices().getTemplates(gt2).actionGet();
        assertTrue("Initially no change", gtr2.getIndexTemplates().isEmpty());
      }

      // Update date and retry

      {
        time_setter.set(2015, 1, 1, 16, 0, 0);
        final Date next_time = time_setter.getTime();
        final DataBucketBean bucket2 =
            BeanTemplateUtils.clone(bucket).with("modified", next_time).done();

        _index_service.handlePotentiallyNewIndex(
            bucket2,
            Optional.empty(),
            ElasticsearchIndexConfigUtils.buildConfigBeanFromSchema(bucket2, _config_bean, _mapper),
            "_default_");

        final GetIndexTemplatesRequest gt2 = new GetIndexTemplatesRequest().names(template_name);
        final GetIndexTemplatesResponse gtr2 =
            _crud_factory.getClient().admin().indices().getTemplates(gt2).actionGet();
        assertEquals(1, _index_service._bucket_template_cache.size());
        assertEquals(1, gtr2.getIndexTemplates().size());

        assertTrue(
            "Mappings should be equivalent",
            ElasticsearchIndexService.mappingsAreEquivalent(
                gtr2.getIndexTemplates().get(0), mapping_json, _mapper));
      }
    }
  }